/*******************************************************************************
 * Copyright (c) 2013, 2014 EclipseSource and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    EclipseSource - initial API and implementation
 ******************************************************************************/
package org.apache.hop.core.database;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.hop.core.Const;
import org.apache.hop.core.util.StringUtil;

public class RunPython {

  // 创建Agent--全部通过llmdb来实现
  private static final String CN_CREATE_AGENT = "AgentCreate.py";
  // 导入向量库--全部通过llmdb来实现
  private static final String CN_DIR2VEC = "RagDir2vec.py";
  // rag查询--全部通过llmdb来实现
  private static final String CN_RAGCHAT = "RagChat.py";
  // chat聊天--全部通过llmdb来实现
  private static final String CN_CHAT = "Chat.py";
  // 把环境变量保存到数据库
  private static final String CN_SAVE_ENV = "SaveEnv.py";

  public RunPython() {}

  /**
   * 运行python代码
   *
   * @param param 参数
   * @return python返回值
   * @throws IOException
   * @throws InterruptedException
   */
  public static String run(String[] param) throws IOException, InterruptedException {
    System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
    ArrayList<String> cmdList = new ArrayList<>();
    cmdList.add("python");
    cmdList.addAll(Arrays.asList(param));
    for (String arg : cmdList) {
      System.out.println("[bzm]arg : " + arg);
    }
    Process process = new ProcessBuilder(cmdList).start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    StringBuilder ret = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
      ret.append(line).append("\r\n");
    }
    process.waitFor();
    System.out.println("[bzm]RunPython : " + ret);
    return ret.toString();
  }

  /**
   * 通过RAG查询文件
   *
   * @param singleFile 单个文件
   * @return
   * @throws IOException
   * @throws InterruptedException
   */
  public static String runFileChat(String singleFile, String prompt)
      throws IOException, InterruptedException {
    StringBuilder cmd = new StringBuilder();
    if (!StringUtil.isEmpty(singleFile)) {
      StringBuilder kb = new StringBuilder();
      List<String> chunks = RunPython.splitXmlByLines(singleFile, 10000);
      int len = chunks.size();
      String kbName;
      for (int i = 0; i < len; i++) {
        kbName = "kb" + i;
        kb.append(kbName).append(",");
        cmd.append("kb")
            .append(i)
            .append("='''\n")
            .append(chunks.get(i))
            .append("\n")
            .append("'''\n");
      }
      cmd.append("Please answer based on the content of")
          .append(kb)
          .append("\n问题是:")
          .append(prompt)
          .append("\n回答:");
    } else cmd.append(prompt);
    System.out.println(cmd);
    return RunPython.run(new String[] {Const.basePythonDir + RunPython.CN_CHAT, cmd.toString()});
  }

  /***
   * 根据文件路径查询
   * @param dir 路径
   * @param prompt 问题
   * @return 答案
   * @throws IOException
   * @throws InterruptedException
   */
  public static String runDirChat(String dir, String prompt)
      throws IOException, InterruptedException {
    return RunPython.run(new String[] {Const.basePythonDir + RunPython.CN_RAGCHAT, dir, prompt});
  }

  /**
   * 通过python把环境变量写入到llmdb
   *
   * @param env 环境变量的字符串
   * @return 返回值
   */
  public static String saveEnv(String env) {
    try {
      return RunPython.run(new String[] {Const.basePythonDir + RunPython.CN_SAVE_ENV, env});
    } catch (Exception e) {
      return e.getMessage();
    }
  }

  /***
   * 根据描述和路径生成Agent
   * @param prompt 问题
   * @return 答案
   * @throws IOException
   * @throws InterruptedException
   */
  public static String runAgent(String prompt) throws IOException, InterruptedException {
    return RunPython.run(new String[] {Const.basePythonDir + RunPython.CN_CREATE_AGENT, prompt});
  }

  /**
   * @param dir 要更新路径
   * @return 返回值
   * @throws IOException
   * @throws InterruptedException
   */
  public static String loadRag(String dir) throws IOException, InterruptedException {
    return RunPython.run(new String[] {Const.basePythonDir + RunPython.CN_DIR2VEC, dir});
  }

  /**
   * @param filePath
   */
  private static List<String> splitXmlByLines(String filePath, int linesPerChunk) {
    System.out.println("splitXmlByLines=" + filePath);
    List<String> chunks = new ArrayList<>();
    StringBuilder currentChunk = new StringBuilder();
    int lineCount = 0;

    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
      String line;
      while ((line = reader.readLine()) != null) {
        currentChunk.append(line).append("\n"); // 保留换行符
        lineCount++;
        if (lineCount % linesPerChunk == 0) {
          chunks.add(currentChunk.toString());
          currentChunk = new StringBuilder(); // 重置StringBuilder以开始新的块
        }
      }
      // 添加最后一块（如果不足3000行）
      if (currentChunk.length() > 0) {
        chunks.add(currentChunk.toString());
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return chunks;
  }
}
